package pl.diagnoser.client;

import java.util.ArrayList;
import java.util.List;

import pl.diagnoser.client.dto.AppDTO;
import pl.diagnoser.client.dto.UserDTO;
import pl.diagnoser.client.tools.DataGetterService;
import pl.diagnoser.client.tools.DataGetterServiceAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.NamedFrame;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Encoding;
import com.smartgwt.client.types.FormMethod;
import com.smartgwt.client.types.ListGridEditEvent;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.RowEndEditAction;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.UploadItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;

public class SystemProperties extends Canvas {
	
	private static DataGetterServiceAsync dataGetterAsc = GWT.create(DataGetterService.class);
	private TabSet tabSet = new TabSet();
	private Tab users = new Tab();
	private Tab systemUtils = new Tab();
	private ListGrid usersGrid;
	private ListGrid appGrid;
	private UserData userData;
	private AppData appData;
	
	SystemProperties() {
		this.setHeight100();
		this.setWidth100();
		
		
		users.setTitle("Użytkownicy");
		users.setPane(usersLayout());
		
		systemUtils.setTitle("Narzędzia");
		systemUtils.setPane(systemUtilsLayout());
		
		tabSet.setWidth100();
		tabSet.setHeight100();
		tabSet.setTabs(users, systemUtils);
		
		this.addChild(tabSet);
		this.draw();
		
	}
	
	private Canvas systemUtilsLayout() {
		final Canvas mainLayout = new Canvas();
		
		final VLayout layout = new VLayout();
		layout.setHeight(200);
		layout.setWidth100();
		layout.setMembersMargin(10);
		
		NamedFrame frame = new NamedFrame("zonk");
		frame.setHeight("1");
		frame.setWidth("1");
		frame.setVisible(false);
		
		final DynamicForm uploadForm = new DynamicForm(); 
		uploadForm.setWidth(150); 
		uploadForm.setNumCols(2); 
		uploadForm.setEncoding(Encoding.MULTIPART);
		uploadForm.setMethod(FormMethod.POST);
		uploadForm.setAction(GWT.getModuleBaseURL()+"upload" );
		uploadForm.setTarget("zonk");
		
		final UploadItem upload = new UploadItem();
		upload.setName("upload");
		upload.setTitle("Artykuł*");
		
		uploadForm.setItems(upload);
		
		Label label = new Label("* nazwa pliku musi być zgodna z nazwą artykułu");
		label.setHeight(10);
		
		Button uploadButton = new Button("Upload");
		uploadButton.addClickHandler(new ClickHandler() {	
			public void onClick(ClickEvent event) {
				uploadForm.submitForm();
				SystemProperties.uploadComplete();
			}
		});
		
		final ListGridField appID = new ListGridField("appID", "ID");
		appID.setType(ListGridFieldType.FLOAT);
		appID.setHidden(true);
		
		final ListGridField appName = new ListGridField("appName", "Nazwa");
		appName.setType(ListGridFieldType.TEXT);
		appName.setCanEdit(false);
		
		final ListGridField isActive = new ListGridField("isActive", "Aktywna");
		isActive.setType(ListGridFieldType.BOOLEAN);
		
		final ListGridField isSearchMode = new ListGridField("isSearchMode", "Wyszukiwarka");
		isSearchMode.setType(ListGridFieldType.BOOLEAN);
		
		final Button removeApp = new Button("Usuń");
		
		appGrid = new ListGrid();
		appGrid.setWidth(500);
		appGrid.setHeight(250);
		appGrid.setShowAllRecords(true);
		appGrid.setFields(appID, appName, isActive, isSearchMode);
		appGrid.setCanEdit(true);  
		appGrid.setEditEvent(ListGridEditEvent.CLICK); 
		appGrid.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				removeApp.enable();
			}
		});
		appGrid.addEditCompleteHandler(new EditCompleteHandler() {
			public void onEditComplete(EditCompleteEvent event) {
				ListGridRecord record = (ListGridRecord) appGrid.getRecord(event.getRowNum());
				doUpdateApp(record);
				appName.setCanEdit(false);
			}
		});
		
		appData = new AppData( appGrid );
		appData.getRecords();
		
		final Button newApp = new Button("Dodaj");
		newApp.setHeight(18);
		newApp.setWidth(90);
		newApp.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				appName.setCanEdit(true);
				appGrid.startEditingNew();
			}
		});
		
		removeApp.setHeight(18);
		removeApp.setWidth(90);
		removeApp.disable();
		removeApp.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Dictionary.getInstance().remove(appGrid.getSelectedRecords(),"APP",null,appGrid);
				appGrid.removeSelectedData();
			}
		});
		
		final HLayout appButtonLayout = new HLayout();
		appButtonLayout.setWidth(245);
		appButtonLayout.setHeight(10);
		appButtonLayout.setAlign(Alignment.CENTER);
		appButtonLayout.setMembersMargin(10);
		appButtonLayout.addMember(newApp);
		appButtonLayout.addMember(removeApp);
		
		layout.setMembers(uploadForm, label, uploadButton, appButtonLayout, appGrid);
		
		mainLayout.addChild(layout);
		mainLayout.addChild(frame);
		return mainLayout;
	}
	
	public static native void uploadComplete() /*-{
	  $wnd.alert('Upload Complete');
	}-*/;
	
	private Canvas usersLayout() {
		
		final Canvas mainLayout = new Canvas();
		
		final ListGridField userID = new ListGridField("userID", "ID");
		userID.setType(ListGridFieldType.FLOAT);
		userID.setHidden(true);
		
		final ListGridField userName = new ListGridField("userName", "Imię");
		userName.setType(ListGridFieldType.TEXT);
		userName.setRequired(true);
		
		final ListGridField userLastname = new ListGridField("userLastname", "Nazwisko");
		userLastname.setType(ListGridFieldType.TEXT);
		userLastname.setRequired(true);
		
		final ListGridField userLogin = new ListGridField("userLogin", "Login");
		userLogin.setType(ListGridFieldType.TEXT);
		userLogin.setRequired(true);
		
		final ListGridField userPassword = new ListGridField("userPassword", "Hasło");
		userPassword.setType(ListGridFieldType.TEXT);
		userPassword.setRequired(true);
		
		final ListGridField userIsAdministrator = new ListGridField("userIsAdministrator", "Administrator");
		userIsAdministrator.setType(ListGridFieldType.BOOLEAN);
		//userIsAdministrator.setRequired(true);
		
		usersGrid = new ListGrid();
		usersGrid.setWidth(500);
		usersGrid.setHeight(250);
		usersGrid.setShowAllRecords(true);
		usersGrid.setFields(userID, userName, userLastname, userLogin, userPassword, userIsAdministrator);
		usersGrid.setEditEvent(ListGridEditEvent.DOUBLECLICK);
		usersGrid.setListEndEditAction(RowEndEditAction.NEXT);
		usersGrid.addEditCompleteHandler(new EditCompleteHandler() {
			public void onEditComplete(EditCompleteEvent event) {
				if(event.getOldRecord() == null) {
					ListGridRecord newRecord = (ListGridRecord) usersGrid.getRecord(event.getRowNum());
					doSaveUser(newRecord);
				}
			}
		});
		userData = new UserData( usersGrid );
		userData.getRecords();
		
		final Button newUser = new Button("Dodaj");
		newUser.setHeight(18);
		newUser.setWidth(90);
		newUser.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				usersGrid.startEditingNew();
			}
		});
		
		final Button removeUser = new Button("Usuń");
		removeUser.setHeight(18);
		removeUser.setWidth(90);
		removeUser.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				doRemoveUser(usersGrid.getSelectedRecord());
				usersGrid.removeSelectedData();
			}
		});
		
		final HLayout userButtonLayout = new HLayout();
		userButtonLayout.setWidth(245);
		userButtonLayout.setHeight(30);
		userButtonLayout.setMembersMargin(10);
		userButtonLayout.addMember(newUser);
		userButtonLayout.addMember(removeUser);
		
		final VLayout usersLayout = new VLayout();
		usersLayout.addMember(userButtonLayout);
		usersLayout.addMember(usersGrid);
		usersLayout.setTop(10);
		usersLayout.setLeft(10);
		usersLayout.setMembersMargin(5);
		
		mainLayout.addChild(usersLayout);
		return mainLayout;
	}
	
	private void doUpdateApp(ListGridRecord appRecord) {
		Long appID = appRecord.getAttributeAsLong("appID");
		int isActive = (appRecord.getAttributeAsBoolean("isActive") ? 1 : 0);
		int isSearchMode = (appRecord.getAttributeAsBoolean("isSearchMode") ? 1 : 0);
		String appName = appRecord.getAttributeAsString("appName");
		
		if (dataGetterAsc == null) {
			dataGetterAsc = GWT.create(DataGetterService.class);
		}
		
		AsyncCallback<String> callback = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				System.out.println(caught.getMessage());
			}

			public void onSuccess(String result) {
				if(!result.equals("OK"))
					SC.say("Błąd zapisu: " + result);
				else
					appData.getRecords();
			}
		};

		dataGetterAsc.updateApp(appID, isActive, appName, isSearchMode, callback);
	}
	
	private void doSaveUser(ListGridRecord userRecord) {
		int isAdministrator = 0;
		if(userRecord.getAttributeAsBoolean("userIsAdministrator"))
			isAdministrator = 1;
		else
			isAdministrator = 0;
		
		UserDTO user = new UserDTO(userRecord.getAttributeAsString("userName"),
								   userRecord.getAttributeAsString("userLastname"),
								   userRecord.getAttributeAsString("userLogin"),
								   userRecord.getAttributeAsString("userPassword"),
								   isAdministrator);
		
		
		if (dataGetterAsc == null) {
			dataGetterAsc = GWT.create(DataGetterService.class);
		}
		
		AsyncCallback<String> callback = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				System.out.println(caught.getMessage());
			}

			public void onSuccess(String result) {
				if(!result.equals("OK"))
					SC.say("Błąd zapisu: " + result);
				else
					userData.getRecords();
			}
		};

		dataGetterAsc.saveUser(user, callback);
	}
	
	private void doRemoveUser(ListGridRecord userRecord) {
		if (dataGetterAsc == null) {
			dataGetterAsc = GWT.create(DataGetterService.class);
		}
		
		AsyncCallback<String> callback = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				System.out.println(caught.getMessage());
			}

			public void onSuccess(String result) {
				if(!result.equals("OK"))
					SC.say("Błąd zapisu: " + result);
				else
					userData.getRecords();
			}
		};

		dataGetterAsc.removeUser(userRecord.getAttributeAsLong("userID"), callback);
	}
}

class UserRecord extends ListGridRecord {
	
	UserRecord() {}
	UserRecord(long userID, String userName, String userLastname, String userLogin, String userPassword,
			int userIsAdministrator) {
		
		setUserID(userID);
		setUserName(userName);
		setUserLastname(userLastname);
		setUserLogin(userLogin);
		setUserPassword(userPassword);
		setUserIsAdministrator(userIsAdministrator);
	}
	
	public long getUserID() {
		return getAttributeAsLong("userID");
	}
	public void setUserID(long userID) {
		setAttribute("userID", userID);
	}
	
	public String getUserName() {
		return getAttributeAsString("userName");
	}
	public void setUserName(String userName) {
		setAttribute("userName", userName);
	}
	
	public String getUserLastname() {
		return getAttributeAsString("userLastname");
	}
	public void setUserLastname(String userLastname) {
		setAttribute("userLastname", userLastname);
	}
	
	public String getUserLogin() {
		return getAttributeAsString("userLogin");
	}
	public void setUserLogin(String userLogin) {
		setAttribute("userLogin", userLogin);
	}
	
	public String getUserPassword() {
		return getAttributeAsString("userPassword");
	}
	public void setUserPassword(String userPassword) {
		setAttribute("userPassword", userPassword);
	}
	
	public int getUserIsAdministrator() {
		if(getAttributeAsBoolean("userIsAdministrator"))
			return 1;
		else
			return 0;
	}
	public void setUserIsAdministrator(int userIsAdministrator) {
		if(userIsAdministrator == 1)
			setAttribute("userIsAdministrator", true);
		else
			setAttribute("userIsAdministrator", false);
	}
	
	public String getFieldValue(String field) {
		return getAttributeAsString(field);
	}
}

class UserData {
	
	private static DataGetterServiceAsync dataGetterAsc = GWT.create(DataGetterService.class);
	private static ListGrid list;
	
	UserData(ListGrid listGrid) {
		list= listGrid;
	}
	
	public void getRecords() {
		
		final ArrayList<UserRecord> records = new ArrayList<UserRecord>();
		
		if (dataGetterAsc == null) {
			dataGetterAsc = GWT.create(DataGetterService.class);
		}
		
		AsyncCallback<List<UserDTO>> callback = new AsyncCallback<List<UserDTO>>() {
			public void onFailure(Throwable caught) {
				System.out.println(caught.getMessage());
			}

			public void onSuccess(List<UserDTO> result) {
				for(UserDTO user : result) {
					records.add(new UserRecord(user.getLoginID(),
							                   user.getName(),
							                   user.getLastname(),
							                   user.getLogin(),
							                   user.getPassword(),
							                   user.getIsAdministrator()));
				}
				list.setData(records.toArray(new UserRecord[records.size()]));
			}
		};

		dataGetterAsc.getUserList(callback);
	}
}

class AppRecord extends ListGridRecord {
	
	AppRecord() {}
	AppRecord(long appID, String appName, int isActive, int isSearchMode) {
		
		setAppId(appID);
		setAppName(appName);
		setIsActive(isActive);
		setIsSearchMode(isSearchMode);
	}
	
	public long getAppId() {
		return getAttributeAsLong("appID");
	}
	public void setAppId(long appID) {
		setAttribute("appID", appID);
	}
	
	public String getAppName() {
		return getAttributeAsString("appName");
	}
	public void setAppName(String appName) {
		setAttribute("appName", appName);
	}
	
	public int getIsActive() {
		if(getAttributeAsBoolean("isActive"))
			return 1;
		else
			return 0;
	}
	
	public void setIsActive(int isActive) {
		if(isActive == 1)
			setAttribute("isActive", true);
		else
			setAttribute("isActive", false);
	}
	
	public int getIsSearchMode() {
		if(getAttributeAsBoolean("isSearchMode"))
			return 1;
		else
			return 0;
	}
	
	public void setIsSearchMode(int isSearchMode) {
		if(isSearchMode == 1)
			setAttribute("isSearchMode", true);
		else
			setAttribute("isSearchMode", false);
	}
	
	public String getFieldValue(String field) {
		return getAttributeAsString(field);
	}
}

class AppData {
	private static DataGetterServiceAsync dataGetterAsc = GWT.create(DataGetterService.class);
	private static ListGrid list;
	
	AppData(ListGrid listGrid) {
		list= listGrid;
	}
	
	public void getRecords() {
		
		final ArrayList<AppRecord> records = new ArrayList<AppRecord>();
		
		if (dataGetterAsc == null) {
			dataGetterAsc = GWT.create(DataGetterService.class);
		}
		
		AsyncCallback<List<AppDTO>> callback = new AsyncCallback<List<AppDTO>>() {
			public void onFailure(Throwable caught) {
				System.out.println(caught.getMessage());
			}

			public void onSuccess(List<AppDTO> result) {
				for(AppDTO app : result) {
					records.add(new AppRecord(app.getAppId(), app.getAppName(), app.getIsActive(), app.getIsSearchMode()));
				}
				list.setData(records.toArray(new AppRecord[records.size()]));
			}
		};

		dataGetterAsc.getAllApp(callback);
	}
}